<?php

namespace App\Service\OpenShop\Feishu;


use App\Enums\OpenShop\InvestmentPromotion\ErrCode;
use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\OrganizationManageEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteMissionEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserBaseInfoEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserContractEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserExperienceEnum;
use App\Enums\OpenShop\InvestmentPromotion\UserIdentityCardEnum;
use App\Enums\OpenShop\MissionTemplateCacheEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Exceptions\Custom\ResponseHttpException;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsUserApi;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopAddressModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopLocationModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopMainProcessModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSiteMissionModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSpaceDesignModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopUserBaseInfoModel;
use App\Models\OpenShop\ShopCheckAccept\OpenShopCheckAcceptModel;
use App\Models\OpenShop\Site\OpenShopMissionTemplateModel;
use App\Service\BaseService;
use App\Service\OpenShop\FeishuMini\ProgrammingService;
use App\Service\OpenShop\FeishuMini\SiteLocationFeiShuMiniService;
use App\Service\OpenShop\User\RmsUserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class MissionTemplateService extends BaseService
{
    /**
     * 列表
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection
     */
    public function lists()
    {
        return OpenShopMissionTemplateModel::query()->orderBy('sort')->get()->map(function ($item) {
            return [
                'id'              => $item->id,
                'name'            => $item->name,
                'mainStep'        => $item->mainStep,
                'mainStepText'    => $item->mainStepText,
                'handlerDay'      => $item->handlerDay,
                'handlerType'     => $item->handlerType,
                'handlerTypeText' => $item->handlerTypeText,
            ];
        });
    }

    /**
     * 详情
     * @param int $id
     * @return array
     */
    public function detail(int $id): array
    {
        $template = OpenShopMissionTemplateModel::query()->find($id);
        if (!$template) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_MISSION_TEMPLATE_ID_NULL)
            );
        }

        return $this->templateElement($template);
    }

    /**
     * 通过stepStatus获取模板信息
     * @param int $stepStatus
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public static function getByStepStatus(int $stepStatus)
    {
        return OpenShopMissionTemplateModel::query()->where('stepStatus', $stepStatus)->withoutGlobalScope('isDel')
                                           ->first();
    }

    /**
     * 模板详情的组成元素枚举
     * @param OpenShopMissionTemplateModel $template
     * @return array[]
     */
    private function templateElement(OpenShopMissionTemplateModel $template): array
    {
        switch ($template->stepStatus) {
            case MissionTemplateEnum::STEP_STATUS_0:
                $fields = ['id', 'name', 'missionType', 'mainStep', 'handlerType'];
                break;
            case MissionTemplateEnum::STEP_STATUS_1:
            case MissionTemplateEnum::STEP_STATUS_2:
            case MissionTemplateEnum::STEP_STATUS_4:
            case MissionTemplateEnum::STEP_STATUS_5:
            case MissionTemplateEnum::STEP_STATUS_8:
            case MissionTemplateEnum::STEP_STATUS_12:
            case MissionTemplateEnum::STEP_STATUS_13:
            case MissionTemplateEnum::STEP_STATUS_14:
            case MissionTemplateEnum::STEP_STATUS_16:
            case MissionTemplateEnum::STEP_STATUS_17:
                $fields = [
                    'id',
                    'name',
                    'missionType',
                    'mainStep',
                    'stepStatus',
                    'handlerType',
                    'handlerDay',
                    'extendHandler',
                ];
                break;
            case MissionTemplateEnum::STEP_STATUS_3:
            case MissionTemplateEnum::STEP_STATUS_6:
            case MissionTemplateEnum::STEP_STATUS_7:
            case MissionTemplateEnum::STEP_STATUS_9:
            case MissionTemplateEnum::STEP_STATUS_10:
            case MissionTemplateEnum::STEP_STATUS_11:
            case MissionTemplateEnum::STEP_STATUS_15:
            case MissionTemplateEnum::STEP_STATUS_18:
                $fields = [
                    'id',
                    'name',
                    'missionType',
                    'mainStep',
                    'stepStatus',
                    'handlerType',
                    'handlerDay',
                    'extendHandler',
                    'handlerRole',
                    'handlerRule',
                    'exceptionHandlerId',
                ];
                break;
            default:
                $fields = [];
                break;
        }

        $lists = [
            [
                'field'   => $field = 'id',
                'text'    => '任务序号',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'text',
            ],
            [
                'field'   => $field = 'name',
                'text'    => '任务名称',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'text',
            ],
            [
                'field'   => $field = 'missionType',
                'text'    => '任务类型',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::MISSION_TYPE_TEXT),
            ],
            [
                'field'   => $field = 'mainStep',
                'text'    => '任务所属阶段',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::MAIN_STEP_TEXT),
            ],
            [
                'field'   => $field = 'stepStatus',
                'text'    => '任务所属阶段状态',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::STEP_STATUS_TEXT),
            ],
            [
                'field'   => $field = 'handlerType',
                'text'    => '任务处理人类型',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::HANDLER_TYPE_TEXT),
            ],
            [
                'field'   => $field = 'handlerDay',
                'text'    => '任务处理时间（天）',
                'value'   => (string)$template->$field,
                'disable' => false,
                'input'   => 'text',
            ],
            [
                'field'   => $field = 'extendHandler',
                'text'    => '当前节点是否根据上一节点指派生成处理人',
                'value'   => (string)$template->$field,
                'disable' => true,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::EXTEND_HANDLER_TEXT),
            ],
            [
                'field'   => $field = 'handlerRole',
                'text'    => '任务处理角色（负责人）',
                'value'   => (string)$template->$field,
                'disable' => false,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::HANDLER_ROLE_TEXT),
            ],
            [
                'field'   => $field = 'handlerRule',
                'text'    => '任务处理规则',
                'value'   => (string)$template->$field,
                'disable' => false,
                'input'   => 'select',
                'options' => $this->getOptionsByConst(MissionTemplateEnum::HANDLER_RULE_TEXT),
            ],
            [
                'field'   => $field = 'exceptionHandlerId',
                'text'    => '异常任务处理人（当处理规则未命中触发）',
                'value'   => (string)$template->$field,
                'disable' => false,
                'input'   => 'select',
                'options' =>
                    Cache::remember('getWebUserLists', 3600, function () {
                        return collect(RmsUserService::getWebUserList())->map(function ($item) {
                            return [
                                'text'  => $item['username'],
                                'value' => (string)$item['id'],
                            ];
                        })->toArray();
                    }),
            ],
        ];

        $res = [];
        foreach ($lists as $elements) {
            if (in_array($elements['field'], $fields)) {
                $res[] = $elements;
            }
        }

        return $res;
    }

    /**
     * 将const转换成options
     * @param array $const
     * @return array
     */
    private function getOptionsByConst(array $const): array
    {
        $res = [];
        foreach ($const as $value => $text) {
            $res[] = [
                'text'  => $text,
                'value' => (string)$value,
            ];
        }

        return $res;
    }

    /**
     * 编辑
     * @param array $requestData
     * @param int $id
     * @return int
     */
    public function edit(array $requestData, int $id): int
    {
        $template = OpenShopMissionTemplateModel::query()->find($id);
        if (!$template) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_MISSION_TEMPLATE_ID_NULL)
            );
        }

        // 设置可编辑的参数
        $templateModel = new OpenShopMissionTemplateModel;
        foreach ($this->templateElement($template) as $elements) {
            if (!$elements['disable']) {
                $elementsField                 = $elements['field'];
                $templateModel->$elementsField = $requestData[$elementsField] ?? null;
            }
        }

        return $templateModel->editData($id);
    }

    private string $orderNo;
    private int    $stepStatus;

    /**
     * 获取下一个节点的处理人
     * @param string $orderNo
     * @param int $stepStatus 下个节点的stepStatus
     */
    public function getNextHandlerId(string $orderNo, int $stepStatus): int
    {
        $this->orderNo    = $orderNo;
        $this->stepStatus = $stepStatus;

        /**
         * 模板信息
         * @var OpenShopMissionTemplateModel $template
         */
        $template = OpenShopMissionTemplateModel::query()->where('stepStatus', $stepStatus)->withoutGlobalScope('isDel')
                                                ->first();
        if (!$template) {
            throw new CustomHttpResponseException(
                ErrCode::errCodeTrans(ErrCode::CODE_MISSION_TEMPLATE_ID_NULL)
            );
        }

        // 默认延续上一个处理人
        if ($template->extendHandler == MissionTemplateEnum::EXTEND_HANDLER_1) {

            // 商家
            if ($template->handlerType == MissionTemplateEnum::HANDLER_TYPE_MERCHANT) {
                return $this->extendHandlerMerchant();
            }

            // 内部员工
            $uid = $this->extendHandlerInternal();
        } else {

            // 根据配置生成下一个处理人
            $uid = $this->extendHandlerTemplate($template, $orderNo);
        }

        // 校验用户状态
        $rmsUser    = RmsUserService::getRmsUserInfoByUserIds([$uid]);
        $userStatus = $rmsUser['data'][0]['status'] ?? RmsUserService::USER_STATUS_BAN;
        $userName   = $rmsUser['data'][0]['username'] ?? '';
        if ($userStatus != RmsUserService::USER_STATUS_NORMAL) {

            // 报警
            $uid       = $template->exceptionHandlerId;
            $title     = '任务模板获取下个节点处理人失败，处理人账号已被禁用或不存在';
            $fsContent = "orderNo:{$orderNo} stepStatus:{$stepStatus} uid:{$uid} username:{$userName}" . PHP_EOL . "已移交异常处理人:{$uid}";
            SendFs::newRobot()->setTitleContent($title, $fsContent)->send();
        }

        return $uid;
    }

    /**
     * 延续上一个处理人 - 内部员工
     * @return int
     */
    private function extendHandlerInternal(): int
    {
        switch ($this->stepStatus) {
            case MissionTemplateEnum::STEP_STATUS_4:
                // 找开发经理
                return (new OpenShopLocationModel)->getAssignUid($this->orderNo);

            case MissionTemplateEnum::STEP_STATUS_8:
            case MissionTemplateEnum::STEP_STATUS_13:
                // 找设计师
                return (new OpenShopSpaceDesignModel)->getAssignUid($this->orderNo);

            case MissionTemplateEnum::STEP_STATUS_12:
                // 找验收人
                return (new OpenShopCheckAcceptModel)->getAssignUid($this->orderNo);
        }

        throw new CustomHttpResponseException(
            ErrCode::errCodeTrans(ErrCode::CODE_EXTEND_HANDLER_INTERNAL_NULL,
                ErrCode::CODE_CN[ErrCode::CODE_EXTEND_HANDLER_INTERNAL_NULL] . " stepStatus:{$this->stepStatus}")
        );
    }

    /**
     * 延续上一个处理人 - 商家
     * @return int
     */
    private function extendHandlerMerchant(): int
    {
        $mobile = (string)OpenShopUserBaseInfoModel::query()->where('orderNo', $this->orderNo)->value('mobile');

        // 根据手机号查询商家的rmsUserId
        return (new RmsUserApi)->getUserInfoByMobiles([$mobile])['data'][0]['id'] ?? -1;
    }

    /**
     * 根据模板配置生成处理人
     * @param OpenShopMissionTemplateModel $template
     * @param string $orderNo
     * @return int
     */
    private function extendHandlerTemplate(OpenShopMissionTemplateModel $template , string $orderNo = ''): int
    {
        if (in_array($template->handlerRule,
            [MissionTemplateEnum::HANDLER_RULE_AREA, MissionTemplateEnum::HANDLER_RULE_HQ])) {

            // 根据配置生成下一个处理人
            if ($template->handlerRule == MissionTemplateEnum::HANDLER_RULE_AREA) {
                $type = OrganizationManageEnum::TYPE_BRANCH_OFFICE;
            } else {
                $type = OrganizationManageEnum::TYPE_HEADQUARTERS;
            }

            //根据订单号获得是否是重点城市
            //$keyPoint = SiteLocationFeiShuMiniService::getKeyPointByOrderNo($orderNo);

            //指派开发顾问特殊处理
//            if ($template->stepStatus == MissionTemplateEnum::STEP_STATUS_3) {
//                $assignHandlerUserInfo = SiteLocationFeiShuMiniService::getAssignHandlerConfig();
//                if (null !== $assignHandlerUserInfo) {
//                    $handlerId = $assignHandlerUserInfo->rmsUserId;
//                } else {
//                    $handlerId = 0;
//                }
//            } else {
//                // 查询订单的省区编号
//                $provinceCode = (int)OpenShopAddressModel::getData($this->orderNo)->provinceCode ?? 0;
//
//                try {
//                    // 指定处理人
//                    $manager = OrganizationManageService::getOrganizationInfoByType($type, $provinceCode);
//                } catch (\Exception $e) {
//                    Log::warning($e);
//                }
//
//                $handlerColumn = MissionTemplateEnum::HANDLER_ROLE_COLUMN[$template->handlerRole] ?? '';
//                $handlerId     = $manager[$handlerColumn] ?? 0;
//            }

            // 查询订单的省区编号
            $openShopAddress = OpenShopAddressModel::getData($this->orderNo);
            $provinceCode    = (int)$openShopAddress->provinceCode ?? 0;
            $cityCode        = (int)$openShopAddress->cityCode ?? 0;

            $handlerColumn = MissionTemplateEnum::HANDLER_ROLE_COLUMN[$template->handlerRole] ?? '';

            // 指派开发顾问特殊处理
            if ($type == OrganizationManageEnum::TYPE_BRANCH_OFFICE && $template->stepStatus == MissionTemplateEnum::STEP_STATUS_3) {
                $manager   = OrganizationManageService::getOrganizationInfoByProvinceCodeCode(
                    $provinceCode, $cityCode, 1
                );
                $handlerId = $manager->operationUid ?? 0;
            } else {
                try {
                    // 指定处理人
                    $manager = OrganizationManageService::getOrganizationInfoByType($type, $provinceCode);
                } catch (\Exception $e) {
                    Log::warning($e);
                }

                $handlerId = $manager[$handlerColumn] ?? 0;
            }

        } elseif ($template->handlerRule == MissionTemplateEnum::HANDLER_RULE_ORDER) {

            $mainProcessId = (int)OpenShopMainProcessModel::query()->where('orderNo', $this->orderNo)->value('id');

            // 根据任务类型，选择对应的顾问
            $managerType = MissionTemplateEnum::HANDLER_ROLE_TO_MANAGER_TYPE[$template->handlerRole] ?? 0;
            if ($managerType) {
                $handlerId = OpenShopOrderManagerModel::getManagerUid($mainProcessId, $managerType);
            } else {
                $fsContent = "orderNo: {$this->orderNo} stepStatus:{$this->stepStatus}";
                SendFs::newRobot()->setTitleContent('按订单指派未处理stepStatus', $fsContent)->send();
            }

        } else {
            throw new ResponseHttpException(\App\Enums\BaseErrorCode::$TEMPLATE_HANDLER_RULE_FAIL);
        }

        // 找不到就异常处理人，飞书通知
        if (!$handlerId) {
            $handlerId = $template->exceptionHandlerId;

            if ($handlerId) {

                // 自动匹配异常处理人
                $title = '任务模板获取下个节点处理人失败，自动匹配异常处理人';
            } else {

                // 未匹配到异常处理人
                $title = '任务模板获取下个节点处理人失败，未匹配到异常任务处理人';
            }

            // 报警
            $address = (string)OpenShopUserBaseInfoModel::query()
                                                        ->where('orderNo', $this->orderNo)
                                                        ->value('addressPrefix');

            $fsContent = "orderNo: {$this->orderNo} stepStatus:{$this->stepStatus} address: {$address}";
            SendFs::newRobot()->setTitleContent($title, $fsContent)->send();
        }

        return $handlerId;
    }

    /**
     * 获取当前模板的完整流程
     * @return array
     */

    public static function getStepStatusSortLists(): array
    {
        return Cache::remember(MissionTemplateCacheEnum::getStepStatusSortLists(), 3600, function () {
            return OpenShopMissionTemplateModel::query()->orderBy('sort')->pluck('stepStatus')->toArray();
        });
    }

    /**
     * 获取sort
     * @param int $stepStatus
     * @return int
     */
    public static function getSortByStepStatus(int $stepStatus): int
    {
        if ($stepStatus == MissionTemplateEnum::STEP_STATUS_999) {
            return 999;
        }

        return (array_flip(self::getStepStatusSortLists())[$stepStatus] ?? 0) + 1;
    }

    /**
     * 获取下个阶段的stepStatus
     * @param string $orderNo
     * @param int $currentStepStatus
     * @return int
     */
    public function getNextStepStatus(string $orderNo, int $currentStepStatus): int
    {
        $mainProcess = OpenShopMainProcessModel::query()
                                               ->where('orderNo', $orderNo)
                                               ->select('stepStatusLists')
                                               ->first();
        if (!$mainProcess) {
            throw new CustomHttpResponseException(ErrCode::errCodeTrans(ErrCode::CODE_SIGN_ORDER_NO_NULL));
        }

        $stepStatusArr = json_decode($mainProcess->stepStatusLists, true);
        foreach ($stepStatusArr as $k => $v) {
            if ($v != $currentStepStatus) {
                continue;
            }

            // 最后一步，没下一步了
            if (!isset($stepStatusArr[$k + 1])) {
                return -1;
            }

            // 正常找到，+1返回
            return $stepStatusArr[$k + 1];
        }

        // db流程中，未找到传入的stepStatus
        throw new CustomHttpResponseException(
            ErrCode::errCodeTrans(ErrCode::CODE_MAIN_PROCESS_MISS_STEP_STATUS,
                ErrCode::CODE_CN[ErrCode::CODE_MAIN_PROCESS_MISS_STEP_STATUS . ':' . $currentStepStatus])
        );
    }
}
